package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

var db *DB
var config *Config

const top = `
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Recipe Index</title>

    <!-- CCS -->

    <style type="text/css">
      .tags {
        display: inline-block;
      }
      .tag {
        float: left;
        display: inline-block;
        padding: 5pt;
        font-family: Helvetica;
      }
      .tag:hover {
        border: 2pt solid black;
        padding: 4pt;
      }
      .selected {
        color: black;
      }
      .unselected {
        color: grey;
      }
      .name {
        text-align: center;
        font-size: 12pt;
        font-family: Helvetica;
        padding-top: 3pt;
        padding-bottom: 3pt;
	color: black;
      }
      .recipetags {
        text-align: left;
        font-size: 8pt;
        font-style: italic;
        color: grey;
      }
      .cell {
        border: 1pt solid black;
        margin: 3pt;
        padding: 3pt;
        max-width: 270pt !important;
        float: left;
        display: inline;
      }
      .cell:hover {
        border: 3pt solid black;
        padding: 1pt;
      }
    </style>

    <!-- JAVASCRIPT -->

    <script type="text/javascript">

      function tag_clicked(tag) 
			{
        t = document.getElementById(tag)
        if(t.className == "tag selected")
          t.className = "tag unselected";
				else
          t.className = "tag selected";
				showHideRecipes();
      }

			function showHideRecipes()
			{
				var act_tags = document.getElementsByClassName('selected');
				var tags = []
				for (var i=0; i<act_tags.length; i++)
					tags.push(act_tags[i].id);

				var elems = document.getElementsByClassName('recipetags');
				for (var i=0; i<elems.length; i++) {
					var n = elems[i].innerHTML.split(", ");
					var found = false;
					for (var j=0; j<n.length; j++) {
						if (tags.indexOf(n[j]) != -1) {
							elems[i].parentElement.style.display = "inline";
							found = true;
							break;
						}
					}
					if (!found)
						elems[i].parentElement.style.display = "none";
				}
			}
    
    </script>

  </head>
  <body>
    <h1>Índice de Receitas</h1><hr>
`

const bottom = `
  </body>
</html>`

func serve(cfg *Config) error {
	// open DB
	var err error
	db, err = initDB(cfg)
	if err != nil {
		return err
	}
	config = cfg
	
	http.Handle("/", http.HandlerFunc(serveIndex))
	http.Handle("/local/", http.HandlerFunc(localFiles))
	http.Handle("/recipe/", http.HandlerFunc(serveRecipe))
	err = http.ListenAndServe("0.0.0.0:8080", nil)
	return err
}


func serveIndex(w http.ResponseWriter, r *http.Request) {
	// find tags
	nametags, ntags := db.tags()
	tags := "<div class='tags'>"
	for _, tag := range nametags {
                tags += "<div class='tag selected' onclick='tag_clicked(\"" + 
                        tag + "\");' id='" + tag + "'>"
		tags += fmt.Sprintf("%s(%d) ", tag, ntags[tag])
                tags += "</div>"
	}
        tags += "</div>"

	// find recipes
        table := ""
	for _, recipe := range db.recipes {
		table += "<a href='recipe/" + recipe.code + "'>";
		table += "<div class='cell');'>"
		table += "<div class='image'>"
		table += fmt.Sprintf("<img src='%s' width='250' alt='" + recipe.name + "'>", 
				localURL(config, recipe.image))
		table += "</div>"
		table += "<div class='name'>" + recipe.name + "</div>"
                table += "<div class='recipetags'>" + strings.Join(recipe.tags, ", ") + "</div>"
		table += "</div>"
		table += "</a>";
	}
	
	// reply
	w.Write([]byte(top + tags + "<hr>" + table + bottom))
}


func localURL(cfg *Config, link string) string {
	var p string
	prefixes := []string{ "http://", "https://", "ftp://" }
	for _, prefix := range prefixes {
		if strings.HasPrefix(link, prefix) {
			p = prefix
		}
	}
	if p != "" {
		return strings.Replace(
			fmt.Sprintf("http://127.0.0.1:8080/local/%s", 
					link[len(p):]),	"\\", "/", -1)
	}
	return link
}


func localFiles(w http.ResponseWriter, r *http.Request) {
	filename := config.dbPath + "/" + r.RequestURI[7:]
	if strings.HasSuffix(filename, "/") {
		filename += "index.html"
	}
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		http.Error(w, "File not found", 404)
	}
	ctype := http.DetectContentType(b)
	if strings.HasSuffix(filename, "css") {
		ctype = "text/css"
	}
	w.Header().Set("Content-type", ctype)
	w.Write(b)
}


func serveRecipe(w http.ResponseWriter, r *http.Request) {
	code := strings.Split(r.RequestURI, "/")[2]
	
	for _, recipe := range db.recipes {
		if recipe.code == code {
			if strings.HasPrefix(recipe.description, "http://") {
				http.Redirect(w, r, localURL(config, recipe.description), 302)
			} else {
				http.Error(w, "Not implemented", 501)
			}
			return;
		}
	}

	http.Error(w, "Recipe " + code + " not found.", 404)
}
